/*
 * $Id: $
 */
package org.rcgwt.client.ui.grid.renderer;

import org.rcgwt.client.ui.grid.internal.ChildrenElementIterable;
import org.rcgwt.client.ui.grid.internal.model.ITitleCellModel;
import org.rcgwt.client.ui.grid.model.IColumn;
import org.rcgwt.client.ui.grid.theme.CssStyle;

import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.Style.Display;

/**
 * 
 * @author Olivier Oeuillot (latest modification by $Author: $)
 * @version $Revision: $ $Date: $
 */
public class DefaultTitleCellRenderer extends AbstractRenderer<ITitleCellModel>
        implements ITitleCellRenderer {

    protected static final String SUBTYPE_ATTRIBUTE = "_ctx_subtype";

    protected enum TitleCellType {
        DRAGGER, ORDER_MARKER, POPUP_MARKER, TEXT
    }

    public Element render(IViewRenderContext viewRenderContext,
            Element parentElement, ITitleCellModel titleCellModel,
            int renderedIndex) {

        assert parentElement instanceof TableRowElement : "Invalid parent type ("
                + parentElement + ")";

        Element titleCellElement = parentElement.getOwnerDocument()
                .createDivElement();

        Element titleContentElement = createTitleText(viewRenderContext,
                titleCellModel, titleCellElement);
        titleCellElement.appendChild(titleContentElement);

        updateStateMask(viewRenderContext, titleCellElement, titleCellModel);

        updateContent(viewRenderContext, titleCellElement, titleCellModel);

        if (titleCellModel.getColumnModel().getColumn().isResizable()) {
            Element dragger = installSizeDragger(viewRenderContext,
                    titleCellElement, titleCellModel);
            if (dragger != null) {
                titleCellElement.appendChild(dragger);

                if (renderedIndex == 0) {
                    dragger.getStyle().setDisplay(Display.NONE);
                }
            }
        }

        if (titleCellModel.getColumnModel().getColumn().isSortable()) {
            Element orderMarkElement = installOrderMark(viewRenderContext,
                    titleCellElement, titleCellModel);
            if (orderMarkElement != null) {
                titleCellElement.appendChild(orderMarkElement);
            }
        }

        if (true) {
            Element popupMarkElement = installPopupMark(viewRenderContext,
                    titleCellElement, titleCellModel);
            if (popupMarkElement != null) {
                titleCellElement.appendChild(popupMarkElement);
            }
        }

        viewRenderContext.getViewModel().getViewModelElements()
                .setTitleCellElement(titleCellModel, titleCellElement,
                        renderedIndex);

        return titleCellElement;
    }

    private Element createTitleText(IViewRenderContext viewRenderContext,
            ITitleCellModel titleCellModel, Element titleCellElement) {
        Element element = titleCellElement.getOwnerDocument()
                .createDivElement();

        CssStyle style = getTitleTextCssStyle(viewRenderContext, titleCellModel);
        if (style != null) {
            element.setClassName(style.getClassName());
        }

        setSubType(element, TitleCellType.TEXT);
        return element;
    }

    private CssStyle getTitleTextCssStyle(IViewRenderContext viewRenderContext,
            ITitleCellModel titleCellModel) {
        return viewRenderContext.getGridRenderContext().getTheme()
                .getTitleCellTextCssStyle(titleCellModel);
    }

    @Override
    protected void updateContent(IViewRenderContext viewRenderContext,
            Element element, ITitleCellModel titleCellModel) {

        IColumn column = titleCellModel.getColumnModel().getColumn();

        String title = column.getMainTitle();
        if (title == null) {
            title = "Column #" + titleCellModel.getModelIndex();
        }

        Element textElement = searchSubType(element, TitleCellType.TEXT);

        textElement.setInnerText(title);
    }

    protected Element installSizeDragger(IViewRenderContext viewRenderContext,
            Element parentElement, ITitleCellModel titleCellModel) {
        Element element = parentElement.getOwnerDocument().createDivElement();

        CssStyle style = getSizeDraggerCssStyle(viewRenderContext,
                titleCellModel);
        if (style != null) {
            element.setClassName(style.getClassName());
        }

        setSubType(element, TitleCellType.DRAGGER);

        return element;
    }

    private void setSubType(Element element, TitleCellType type) {

        element.setPropertyInt(SUBTYPE_ATTRIBUTE, type.ordinal());
    }

    protected CssStyle getSizeDraggerCssStyle(
            IViewRenderContext viewRenderContext, ITitleCellModel titleCellModel) {
        return viewRenderContext.getGridRenderContext().getTheme()
                .getTitleCellSizeDraggerCssStyle(titleCellModel);
    }

    private Element installOrderMark(IViewRenderContext viewRenderContext,
            Element parentElement, ITitleCellModel titleCellModel) {
        Element element = parentElement.getOwnerDocument().createDivElement();

        CssStyle style = getOrderMarkerCssStyle(viewRenderContext,
                titleCellModel);
        if (style != null) {
            element.setClassName(style.getClassName());
        }

        setSubType(element, TitleCellType.ORDER_MARKER);

        return element;
    }

    protected CssStyle getOrderMarkerCssStyle(
            IViewRenderContext viewRenderContext, ITitleCellModel titleCellModel) {
        return viewRenderContext.getGridRenderContext().getTheme()
                .getTitleCellOrderMarkerCssStyle(titleCellModel);
    }

    private Element installPopupMark(IViewRenderContext viewRenderContext,
            Element parentElement, ITitleCellModel titleCellModel) {
        AnchorElement element = parentElement.getOwnerDocument()
                .createAnchorElement();

        element.setHref("javascript:void(0");

        CssStyle style = getPopupMarkerCssStyle(viewRenderContext,
                titleCellModel);
        if (style != null) {
            element.setClassName(style.getClassName());
        }

        setSubType(element, TitleCellType.POPUP_MARKER);

        Element arrow = parentElement.getOwnerDocument().createDivElement();
        element.appendChild(arrow);

        if (style != null) {
            arrow.setClassName(style.getClassName() + "-arrow");
        }

        return element;
    }

    protected CssStyle getPopupMarkerCssStyle(
            IViewRenderContext viewRenderContext, ITitleCellModel titleCellModel) {
        return viewRenderContext.getGridRenderContext().getTheme()
                .getTitleCellPopupMarkerCssStyle(titleCellModel);
    }

    @Override
    public void updateLayout(IViewRenderContext viewRenderContext,
            ITitleCellModel titleCellModel, Element titleCellElement,
            int width, int height) {

        Style style = titleCellElement.getStyle();

        style.setPropertyPx(Styles.WIDTH, width);

        if (height > 0) {
            style.setPropertyPx(Styles.HEIGHT, height);

            if (titleCellModel.getColumnModel().getColumn().isResizable()) {
                Element draggerElement = searchSubType(titleCellElement,
                        TitleCellType.DRAGGER);

                if (draggerElement != null) {
                    draggerElement.getStyle().setPropertyPx(Styles.HEIGHT,
                            height);
                }
            }
        }

        /*
         * Element contentElement = searchSubType(titleCellElement,
         * TitleCellTypes.TEXT);
         * 
         * if (contentElement != null) {
         * 
         * }
         */
    }

    private TitleCellType getTitleCellType(Element element) {
        String ts = element.getPropertyString(SUBTYPE_ATTRIBUTE);
        if (ts == null) {
            return null;
        }

        TitleCellType tc = TitleCellType.values()[Integer.parseInt(ts)];

        return tc;
    }

    private Element searchSubType(Element titleCellElement,
            TitleCellType searchedType) {
        for (Element child : ChildrenElementIterable.iterate(titleCellElement)) {

            TitleCellType tc = getTitleCellType(child);

            if (tc == searchedType) {
                return child;
            }
        }
        return null;
    }

    @Override
    protected CssStyle getCssStyle(IViewRenderContext viewRenderContext,
            ITitleCellModel titleCell) {

        CssStyle cssStyle = viewRenderContext.getGridRenderContext().getTheme()
                .getTitleCellCssStyle(titleCell);

        return cssStyle;
    }

    public boolean isPopupMarkerClicked(IViewRenderContext viewRenderContext,
            ITitleCellModel titleCellModel, Element titleCellElement,
            Element clickedElement) {

        for (; clickedElement != titleCellElement; clickedElement = clickedElement
                .getParentElement()) {
            if (getTitleCellType(clickedElement) == TitleCellType.POPUP_MARKER) {
                return true;
            }
        }

        return false;
    }
}
